package top.hudk.tank.factory;

import top.hudk.tank.config.GameConfig;
import top.hudk.tank.config.ResourceMgr;
import top.hudk.tank.enums.Dir;
import top.hudk.tank.enums.Group;
import top.hudk.tank.frame.AbstractGameFrame;
import top.hudk.tank.frame.TankFrame;
import top.hudk.tank.model.GameApplicationContext;
import top.hudk.tank.model.GameObject;
import top.hudk.tank.utils.DirUtil;
import top.hudk.tank.utils.RandomUtil;

import java.awt.*;
import java.util.List;

/**
 * 作用：
 *
 * @author hudk
 * @date 2020/9/10 7:45
 */
public abstract class Bullet  extends GameObject {
    Bullet() {
    }

    public void init(int x, int y, Dir dir, Group group) {
        setPlace(x, y);
        this.dir = dir;
        this.group = group;
        this.speed = group == Group.GOOD ? GameConfig.GOOD_BULLET_SPEED : GameConfig.BAD_BULLET_SPEED;
        GameApplicationContext.getInstance().add(this);
    }
    /**
     * 子弹方向
     */
    private Dir dir;
    /**
     * 子弹速度
     */
    private int speed = GameConfig.BAD_BULLET_SPEED;

    /**
     * 子弹是否存活
     */
    private boolean living = true;

    /**
     * 子弹的敌我阵营
     */
    private Group group;


    /**
     * 渲染子弹在主窗口上的位置和方向
     *
     * @param g
     */
    @Override
    public void paint(Graphics g, AbstractGameFrame gameFrame) {
        if (!isLiving()) {
            GameApplicationContext.getInstance().remove(this);
            return;
        }
        //绘制位置和外观
        draw(g);
        //移动
        move(gameFrame);
        //随机行为
        randomBehaviour(GameConfig.BAD_BULLET_CHANGE_DIRECTION);
    }

    /**
     * 绘制位置和外观
     *
     * @param g
     */
    public void draw(Graphics g) {
//        g.drawRect(getX(), getY(), getWidth(), getHeight());
//        g.setColor(Color.WHITE);
        switch (getDir()) {
            case LEFT:
                g.drawImage(ResourceMgr.bulletL, getX(), getY(), null);
                break;
            case UP:
                g.drawImage(ResourceMgr.bulletU, getX(), getY(), null);
                break;
            case RIGHT:
                g.drawImage(ResourceMgr.bulletR, getX(), getY(), null);
                break;
            case DOWN:
                g.drawImage(ResourceMgr.bulletD, getX(), getY(), null);
                break;
            default:
                break;
        }
    }

    /**
     * 随机行为
     */
    public void randomBehaviour(int i) {
        //默认敌方子弹会随机改变方向
        if (Group.BAD.equals(getGroup())) {
            turnDir(GameConfig.BAD_BULLET_CHANGE_DIRECTION_BY_SECOND);
        }
    }

    private void turnDir(int secondNumb){
        setDir(DirUtil.randomLeftOrRightDir(getDir(),
                RandomUtil.returnTrueAfterSeconds(secondNumb)));
    }

    /**
     * 子弹移动
     */
    public void move(AbstractGameFrame gameFrame) {
        switch (dir) {
            case LEFT:
                x -= speed;
                break;
            case UP:
                y -= speed;
                break;
            case RIGHT:
                x += speed;
                break;
            case DOWN:
                y += speed;
                break;
            default:
                break;
        }
        rect.x = this.x;
        rect.y = this.y;
        //判断子弹已死
        outCheck(gameFrame);
    }

    /**
     * 判断子弹已出游戏界面
     *
     * @param gameFrame
     */
    public void outCheck(AbstractGameFrame gameFrame) {
        if (x < gameFrame.minX() || y < gameFrame.minY() || x > gameFrame.maxX(this) || y > gameFrame.maxY(this)) {
            living = false;
            return;
        }
    }

    /**
     * 子弹死亡
     */
    public void die() {
        this.living = false;
    }

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }

    public Dir getDir() {
        return dir;
    }

    public void setDir(Dir dir) {
        this.dir = dir;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    public boolean isLiving() {
        return living;
    }

    public void setLiving(boolean living) {
        this.living = living;
    }

}
